<?php

class ExpOperator implements ExpCall
{
	const AR_UNARY = 1;
	const AR_BINARY = 2;

	const OP_PREFIX = 11;
	const OP_OTHER = 12;

	const ASSOC_LEFT = 21;
	const ASSOC_RIGHT = 22;

	const TYPE_PREFIX = 31;
	const TYPE_POSTFIX = 32;
	const TYPE_LEFT = 33;
	const TYPE_RIGHT = 34;

	const ARRAYOP = '[]';

	private $name;
	private $call;
	private $prec;
	private $assoc;
	private $arity;

	private static $typeinfo = array(
		self::TYPE_PREFIX => array(
			'assoc' => self::ASSOC_RIGHT,
			'arity' => self::AR_UNARY,
		),
		self::TYPE_POSTFIX => array(
			'assoc' => self::ASSOC_LEFT,
			'arity' => self::AR_UNARY,
		),
		self::TYPE_LEFT => array(
			'assoc' => self::ASSOC_LEFT,
			'arity' => self::AR_BINARY,
		),
		self::TYPE_RIGHT => array(
			'assoc' => self::ASSOC_RIGHT,
			'arity' => self::AR_BINARY,
		),
	);

	public function __construct ($op, $group, $mode)
	{
		$info = $mode->getOperator($op, $group);
		$call = $mode->getCall($info['name'], CliMode::ID_OPERATOR);

		$this->call = $call;
		$this->name = $info['name'];
		$this->prec = $info['prec'];
		$this->assoc = self::$typeinfo[$info['type']]['assoc'];
		$this->arity = self::$typeinfo[$info['type']]['arity'];
	}

	public function call (ArgContext $args)
	{
		return CliLib::doCall($this->name, $this->call, $args);
	}

	public function argCount ()
	{
		return $this->arity === self::AR_UNARY ? 1 : 2;
	}

	public function getPrec ()
	{
		return $this->prec;
	}

	public function getAssoc ()
	{
		return $this->assoc;
	}

	public function isArrayOperator ()
	{
		return $this->name == self::ARRAYOP;
	}

	public function __toString ()
	{
		return $this->name;
	}

}

?>